﻿namespace JoinBox.Basal;

using System;
using System.Collections.Generic;
using System.Text;

public partial class WindowsAPI
{
    // 窗口样式
    public struct WindowInfo
    {
        public IntPtr Hwnd;
        public string WindowName;
        public string ClassName;
        public RECT Rect;
        public int LParam;

        public WindowInfo(IntPtr hWnd, int lParam)
        {
            Hwnd = hWnd; // 句柄
            LParam = lParam;

            var sb = new StringBuilder(256);
            GetWindowText(hWnd, sb, sb.Capacity); // 获取窗口名称
            WindowName = sb.ToString();

            GetClassName(hWnd, sb, sb.Capacity);// 获取窗口类
            ClassName = sb.ToString();

            GetWindowRect(hWnd, out Rect);
            // GetWindowZOrder(hWnd, out ZOrder);
        }
    }


    /// <summary>
    /// 获取窗口的z轴
    /// </summary>
    /// <param name="hwnd"></param>
    /// <param name="zOrder"></param>
    /// <returns></returns>
    public static bool GetWindowZOrder(IntPtr hwnd, out int zOrder)
    {
        var lowestHwnd = GetWindow(hwnd, GetWindowCmd.GW_HWNDLAST);

        var z = 0;
        var hwndTmp = lowestHwnd;
        while (hwndTmp != IntPtr.Zero)
        {
            if (hwnd == hwndTmp)
            {
                zOrder = z;
                return true;
            }

            hwndTmp = GetWindow(hwndTmp, GetWindowCmd.GW_HWNDPREV);
            z++;
        }
        zOrder = int.MinValue;
        return false;
    }

    /// <summary>
    /// 枚举所有桌面窗口
    /// </summary>
    /// <param name="wndList">用来保存窗口对象 列表</param>
    /// <returns></returns>
    public static bool GetAllDesktopWindows(List<WindowInfo> wndList)
    {
        try
        {
            EnumWindows((hWnd, lParam) =>
            {
                var wnd = new WindowInfo(hWnd, lParam);
                wndList.Add(wnd);
                return true;
            }, 0);
        }
        catch
        {
            return false;
        }
        return true;
    }

    /// <summary>
    /// 枚举父窗口下的所有子窗口
    /// </summary>
    /// <param name="hWnd">父窗口</param>
    /// <param name="wndList">用来保存窗口对象 列表</param>
    /// <returns></returns>
    public static bool GetAllDesktopWindows(IntPtr Handle, List<WindowInfo> wndList)
    {
        try
        {
            EnumChildWindows(Handle, (hWnd, lParam) =>
            {
                var wnd = new WindowInfo(hWnd, lParam);
                wndList.Add(wnd);
                return true;
            }, 0);
        }
        catch
        {
            return false;
        }
        return true;
    }

    /// <summary>
    /// 递归查找子窗体句柄
    /// </summary>
    /// <param name="hwnd">开始的句柄</param>
    /// <param name="classArrar">要查找旗下的className数组</param>
    /// <param name="arrNum">数组第几个</param>
    /// <returns></returns>
    public static IntPtr RecursionFindWindowClassName(IntPtr hwnd, string[] classArrar, int arrNum = 0)
    {
        IntPtr fi = IntPtr.Zero;
        if (classArrar.Length > arrNum)
        {
            fi = FindWindowEx(hwnd, 0, classArrar[arrNum], null);
            if (fi != IntPtr.Zero && classArrar.Length > arrNum + 1)// 最后一个就不找了
                fi = RecursionFindWindowClassName(fi, classArrar, ++arrNum);
        }
        return fi;
    }
}